var createError = require('http-errors')
const express = require('express')
var cookieParser = require('cookie-parser')
const session = require('express-session')
const md5 = require('md5')
var { expressjwt: jwt } = require('express-jwt')
const { ForbiddenError, ServiceError, UnknownError, ValidationError } = require('./utils/errors')
const path = require('path')

// 默认读取项目根目录下的 .env 环境变量文件
require('dotenv').config()
//全局错误处理
require('express-async-errors')
// 引入数据库连接
require('./dao/db')
// 引入路由
const adminRouter = require('./routes/admin')
const aboutRouter = require('./routes/about')
const captchaRouter = require('./routes/captcha')
var blogTypeRouter = require('./routes/blogType')
const bannerRouter = require('./routes/banner')
const settingRouter = require('./routes/setting')
const uploadRouter = require('./routes/upload')
const demoRouter = require('./routes/demo')
const blogRouter = require('./routes/blog')
const messageRouter = require('./routes/message')
const ipAddress = require('./routes/ipAddress')
const visitorInfo = require('./routes/visitorInfo')
const newMessageRouter = require('./routes/newMessage')
const app = express()
const cors = require('cors');
app.use(cors());
app.use(
  session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
  })
)
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(express.static(path.join(__dirname, 'public')))
// app.use('/userimg/', express.static('./public/static/userimg/'))  
// app.use('/rootimg/', express.static('./public/static/rootimg/'))  
// 配置验证 token 接口
const authenticate = jwt({
  secret: md5(process.env.JWT_SECRET), // 我们所设置的秘钥
  algorithms: ['HS256'], // 新版本的 expressJWT 必须要求指定算法
}).unless({
  // 需要排除的 token 验证的路由
  path: [
    { url: '/api/admin/login', methods: ['POST'] },
    { url: '/api/admin/regist', methods: ['POST'] },
    { url: '/res/captcha', methods: ['GET'] },
    { url: '/api/captcha', methods: ['GET'] },
    { url: '/api/banner', methods: ['GET'] },
    { url: '/api/blogtype', methods: ['GET'] },
    { url: '/api/blog', methods: ['GET'] },
    { url: /\/api\/blog\/./, methods: ['GET'] },
    { url: '/api/project', methods: ['GET'] },
    { url: '/api/message', methods: ['GET', 'POST'] },
    { url: '/api/comment', methods: ['GET', 'POST'] },
    { url: '/api/about', methods: ['GET'] },
    { url: '/api/setting', methods: ['GET'] },
    { url: '/api/ipAddress', methods: ['GET'] },
    { url: '/api/visitorInfo', methods: ['GET'] },
    { url: '/api/captcha/verifyCode', methods: ['POST'] },
    { url: '/img', methods: ['GET', 'POST'] },
    { url: '/static', methods: ['GET', 'POST'] },
  ],
})
// 排除/api/newMessage开头的路由token 验证
const excludeRoutes = /^\/api\/newMessage\//;
app.use((req, res, next) => {
  if (excludeRoutes.test(req.path)) {
    return next();
  }
  return authenticate(req, res, next);
});
//引入路由中间件
app.use('/api/admin', adminRouter)
app.use('/api/about', aboutRouter)
app.use('/api/captcha', captchaRouter)
app.use('/api/banner', bannerRouter)
app.use('/api/upload', uploadRouter)
app.use('/api/setting', settingRouter)
app.use('/api/project', demoRouter)
app.use('/api/blogtype', blogTypeRouter)
app.use('/api/blog', blogRouter)
app.use('/api/message', messageRouter)
app.use('/api/comment', messageRouter)
app.use('/api/newMessage', newMessageRouter)
//前台评论时需要验证码
app.use('/api/captcha', captchaRouter)
app.use('/api/captcha/verifyCode', captchaRouter)
app.use('/api/ipAddress', ipAddress)
app.use('/api/visitorInfo',visitorInfo)
// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404))
})
// error handler
app.use(function (err, req, res, next) {
  console.log('err.name>>>', err.name)
  console.log('err.message>>>', err.message)
  if (err.name === 'UnauthorizedError' || err.name === 'TokenExpiredError') {
    // 说明是 token 验证错误，接下来我们来抛出我们自定义的错误
    res.send(new ForbiddenError('未登录，或者登录已经过期').toResponseJSON())
  } else if (err instanceof ServiceError) {
    res.send(err.toResponseJSON())
  } else if (err instanceof ValidationError) {
    res.send(err.toResponseJSON())
  } else {
    res.send(new UnknownError().toResponseJSON())
  }
})

module.exports = app
